package com.demo.config;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.springframework.stereotype.Component;

@ChannelHandler.Sharable
@Component
public class ModbusTcpServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf buf = (ByteBuf) msg;

        try {
            // 解析Modbus TCP报文
            int transactionId = buf.readShort(); // 事务标识符
            int protocolId = buf.readShort();    // 协议标识符(应为0)
            int length = buf.readShort();       // 剩余长度
            byte unitId = buf.readByte();       // 单元标识符
            byte functionCode = buf.readByte(); // 功能码

            System.out.println("Received Modbus request: ");
            System.out.println("Transaction ID: " + transactionId);
            System.out.println("Function Code: " + functionCode);

            // 根据功能码处理请求
            ByteBuf response = processModbusRequest(buf, transactionId, unitId, functionCode);

            // 发送响应
            ctx.writeAndFlush(response);
        } finally {
            buf.release();
        }
    }

    private ByteBuf processModbusRequest(ByteBuf buf, int transactionId, byte unitId, byte functionCode) {
        ChannelHandlerContext ctx = null;
        ByteBuf response = ctx.alloc().buffer();

        // 写入MBAP头
        response.writeShort(transactionId); // 事务标识符
        response.writeShort(0);             // 协议标识符
        response.writeShort(0);             // 长度占位(后面更新)
        response.writeByte(unitId);         // 单元标识符

        // 根据功能码处理
        switch (functionCode) {
            case 0x03: // 读保持寄存器
                int startAddress = buf.readShort();
                int quantity = buf.readShort();

                System.out.printf("Read holding registers - Start: %d, Quantity: %d%n", startAddress, quantity);

                // 写入功能码
                response.writeByte(0x03);
                // 写入字节数
                response.writeByte(quantity * 2);
                // 写入寄存器值(示例数据)
                for (int i = 0; i < quantity; i++) {
                    response.writeShort(i + 100); // 示例值
                }
                break;

            case 0x06: // 写单个寄存器
                int writeAddress = buf.readShort();
                int writeValue = buf.readShort();

                System.out.printf("Write single register - Address: %d, Value: %d%n", writeAddress, writeValue);

                // 写入功能码
                response.writeByte(0x06);
                // 回显地址和值
                response.writeShort(writeAddress);
                response.writeShort(writeValue);
                break;

            default:
                // 错误响应
                response.writeByte(functionCode | 0x80); // 设置错误标志
                response.writeByte(0x01); // 非法功能码
                break;
        }

        // 更新长度字段
        int length = response.readableBytes() - 6; // 减去MBAP头的6字节
        response.setShort(4, length);

        return response;
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}
